package cn.life.business.material.dao.impl;

import cn.life.business.material.dao.MaterialDao;
import cn.life.business.material.entity.po.*;
import cn.life.business.material.entity.vo.MaterialRecVo;
import cn.life.common.entity.vo.Pagination;
import cn.life.common.support.jdbc.AbstractSupportDao;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author 李佳明
 * @Date 2018-07-26 10:17
 */
@Repository
public class MaterialDaoImpl extends AbstractSupportDao implements MaterialDao {

    @Override
    public Long addMaterialRecord(MaterialRecVo materialRecVo) {
        Long id = queryTableNextId("factory_material","record_id");
        String sql ="insert into factory_material(record_id,record_name,team_name,person_liable_name,person_liable_phone,material_person_name,material_person_phone,project_id,audit_state,opr_user_id,opr_user_name,opr_date,json)"
                + "values(?,?,?,?,?,?,?,?,?,?,?,?,?)";
        return update(sql,id,materialRecVo.getRecordName(), materialRecVo.getTeamName(), materialRecVo.getPersonLiableName(), materialRecVo.getPersonLiablePhone(), materialRecVo.getMaterialPersonName(), materialRecVo.getMaterialPersonPhone(), materialRecVo.getProjectId(),1, materialRecVo.getOprUserId(), materialRecVo.getOprUserName(), materialRecVo.getOprDate(),materialRecVo.getJson()) == 1 ? id : null;
    }

    @Override
    public int addMaterialDetailRecord(MaterialRecVo materialRecVo) {
        String sql ="insert into factory_material_detail(record_id,material_id,material_name,material_model,material_number,entering_plant_date,material_purpose,material_desc)"
                + "values(?,?,?,?,?,?,?,?)";
        List<Object[]> list = new ArrayList<>();
        for(MaterialDetailRecPo detailPo : materialRecVo.getList()){
            Object[] objects = new Object[8];
            objects[0] = materialRecVo.getRecordId();
            objects[1] = detailPo.getMaterialId();
            objects[2] = detailPo.getMaterialName();
            objects[3] = detailPo.getMaterialModel();
            objects[4] = detailPo.getMaterialNumber();
            objects[5] = detailPo.getEnteringPlantDate();
            objects[6] = detailPo.getMaterialPurpose();
            objects[7] = detailPo.getMaterialDesc();

            list.add(objects);
        }
        batchUpdate(sql,list);
        return 1;
    }

    @Override
    public int auditMaterialRecord(MaterialRecPo materialRecPo) {
        String sql = "update factory_material set audit_state = ? where record_id = ?";
        return update(sql, materialRecPo.getAuditState(), materialRecPo.getRecordId());
    }

    @Override
    public int addMaterial(MaterialPo materialPo) {
        String sql = "insert into material_info(material_name,material_type_id,material_type_name,material_desc,opr_user_id,opr_user_name,opr_date) values(?,?,?,?,?,?,?)";
        return update(sql,materialPo.getMaterialName(),materialPo.getMaterialTypeId(),materialPo.getMaterialTypeName(),materialPo.getMaterialDesc(),materialPo.getOprUserId(),materialPo.getOprUserName(),materialPo.getOprDate());
    }

    @Override
    public int updateMaterial(MaterialPo materialPo) {
        String sql = "update material_info set material_name = ?,material_type_id = ?,material_type_name = ?,material_desc = ?,json = ? where material_id = ?";
        return update(sql,materialPo.getMaterialName(),materialPo.getMaterialTypeId(),materialPo.getMaterialTypeName(),materialPo.getMaterialDesc(),materialPo.getJson(),materialPo.getMaterialId());
    }

    @Override
    public int deleteMaterial(MaterialPo materialPo) {
        String sql = "delete from material_info where material_id = ?";
        return update(sql,materialPo.getMaterialId());
    }

    @Override
    public int addMaterialType(MaterialTypePo materialTypePo) {
        String sql = "insert into material_type(type_code,type_name,type_desc,parent_id,opr_user_id,opr_user_name,opr_date) values(?,?,?,?,?,?,?)";
        return update(sql,materialTypePo.getTypeCode(),materialTypePo.getTypeName(),materialTypePo.getTypeDesc(),materialTypePo.getParentId(),materialTypePo.getOprUserId(),materialTypePo.getOprUserName(),materialTypePo.getOprDate());
    }

    @Override
    public int updateMaterialType(MaterialTypePo materialTypePo) {
        String sql = "update material_type set type_name = ?,type_desc = ? where type_id = ?";
        return update(sql,materialTypePo.getTypeName(),materialTypePo.getTypeDesc(),materialTypePo.getTypeId());
    }

    @Override
    public int deleteMaterialType(MaterialTypePo materialTypePo) {
        String sql = "delete from material_type where type_id = ?";
        return update(sql,materialTypePo.getTypeId());
    }

    @Override
    public String queryMaxTypeCode(MaterialTypePo materialTypePo) {
        String sql = "";
        if(materialTypePo.getParentId() == null){
            sql = "select max(type_code) from material_type where length(type_code) = 4";
            String code = queryForObject(sql,String.class);
            if(code == null || code.equals("")){
                return "1001";
            }else{
                Integer nextCode = Integer.valueOf(code) + 1;
                return nextCode.toString();
            }
        }else{
            sql = "select type_code from material_type where type_id = ?";
            String typeCode = queryForObject(sql,String.class,materialTypePo.getParentId());
            int length = typeCode.length() + 2;
            String codeSql = "select max(type_code) from material_type where length(type_code) = ? and type_code like '%" + typeCode + "%'";
            String code =  queryForObject(codeSql,String.class,length);
            if(code == null){
                return typeCode + "01";
            }else{
                Integer nextCode = Integer.valueOf(code) + 1;
                return nextCode.toString();
            }
        }
    }

    @Override
    public List<MaterialRecVo> queryRecordList(Long oprUserId,String recordName,Long projectId) {
        if(recordName == null){
            recordName = "";
        }
        String  sql = "select a.*,1 as isMyAudit from factory_material a inner join factory_audit_record b on a.record_id = b.record_id where a.audit_state = 1 and b.rec_state = 1 and b.opr_state = 0 and b.opr_user_id = ? and a.record_name like '%" + recordName + "%' and a.project_id = ? order by audit_state , opr_date desc";
        return queryForList(sql,MaterialRecVo.class,oprUserId,projectId);
    }

    @Override
    public int addMaterialAuditRecord(MaterialAuditPo materialRecPo) {
        String sql = "insert into factory_audit_record(record_id,opr_user_id,opr_user_name,opr_date,opr_state,rec_state) values(?,?,?,?,?,?)";
        return update(sql,materialRecPo.getRecordId(),materialRecPo.getOprUserId(),materialRecPo.getOprUserName(),getNowDate(),materialRecPo.getOprState(),materialRecPo.getRecState());
    }

    @Override
    public Pagination<MaterialPo> queryMaterialList(MaterialPo materialPo) {
        String  sql = "select * from material_info where 1 = 1 ";
        if(materialPo.getMaterialTypeId() != null && !materialPo.getMaterialTypeId().equals("")){
            sql = sql + "and material_type_id = " + materialPo.getMaterialTypeId() + " ";
        }
        if(materialPo.getMaterialName() != null && !materialPo.getMaterialName().equals("")){
            sql = sql + "and material_name like '%" + materialPo.getMaterialName() + "%'";
        }
        return queryForListByPageEx(sql,MaterialPo.class,materialPo.getPageIndex(),materialPo.getPageSize());
    }

    @Override
    public MaterialPo queryMaterialDetail(MaterialPo materialPo) {
        String  sql = "select a.*,b.parent_id as typeParentId,b.type_code as typeParentCode from material_info a left join material_type b on a.material_type_id = b.type_id where a.material_id = ?";
        return queryForObject(sql,MaterialPo.class,materialPo.getMaterialId());
    }

    @Override
    public List<MaterialTypePo> queryMaterialTypeList(MaterialTypePo materialTypePo) {
        String  sql = "select * from material_type where 1 = 1 ";
        if(materialTypePo.getTypeCode() == null || materialTypePo.getTypeCode().equals("")){
            sql = sql + "and length(type_code) = 4";
        }else if(materialTypePo.getTypeCode().equals("all")){
            return queryForList(sql,MaterialTypePo.class);
        }else {
            int length = materialTypePo.getTypeCode().length() + 2;
            sql = sql + "and type_code like '%" + materialTypePo.getTypeCode() + "%' and length(type_code) = " + length;
        }
        return queryForList(sql,MaterialTypePo.class);
    }

    @Override
    public MaterialTypePo queryMaterialTypeDetail(MaterialTypePo materialTypePo) {
        String  sql = "select * from material_type where type_id = ?";
        return queryForObject(sql,MaterialTypePo.class,materialTypePo.getTypeId());
    }

    @Override
    public List<MaterialRecVo> queryOprRecordList(Long oprUserId,String recordName,Long projectId) {
        String sql = "select a.*,0 as isMyAudit from factory_material a inner join factory_audit_record b on a.record_id = b.record_id where b.opr_user_id = ? and b.opr_state <> 0 and a.project_id = ? and a.record_name like '%" + recordName + "%'";
        return queryForList(sql,MaterialRecVo.class,oprUserId,projectId);
    }

    @Override
    public MaterialRecVo queryRecordDetail(MaterialRecVo materialRecVo) {
        String sql = "select * from factory_material where record_id = ?";
        MaterialRecVo vo = queryForObject(sql,MaterialRecVo.class,materialRecVo.getRecordId());
        String detailSql = "select * from factory_material_detail where record_id = ?";
        List<MaterialDetailRecPo> list = queryForList(detailSql,MaterialDetailRecPo.class,materialRecVo.getRecordId());
        vo.setList(list);
        String auditSql = "select * from factory_audit_record where record_id = ? and rec_state = 1";
        List<MaterialAuditPo> auditList = queryForList(auditSql,MaterialAuditPo.class,materialRecVo.getRecordId());
        String nextAuditUserSql = "select a.* from (select rec_id as recId,opr_user_id as nextUserId,opr_user_name as nextUserName from factory_audit_record where record_id = ? and rec_state = 1 order by rec_id desc) a limit 1";
        Map<String,Object> nextUser = queryForMap(nextAuditUserSql,materialRecVo.getRecordId());
        if(nextUser != null && nextUser.get("nextUserId") != null){
            vo.setNextUserId((Long)nextUser.get("nextUserId"));
            vo.setNextUserName(nextUser.get("nextUserName").toString());
            vo.setIsMyAudit(0);
        }
        //去除下一审核人信息
        if(nextUser != null && nextUser.get("recId") != null && auditList.size() > 0){
            for(MaterialAuditPo auditPo : auditList){
                if(auditPo.getRecId().equals(nextUser.get("recId"))){
                    auditList.remove(auditPo);
                    break;
                }
            }
        }
        vo.setAuditList(auditList);
        return vo;
    }

    @Override
    public Integer deleteMaterialDetailRecord(MaterialRecVo materialRecVo) {
        String sql = "delete from factory_material_detail where record_id = ?";
        return update(sql,materialRecVo.getRecordId());
    }

    @Override
    public Integer updateMaterialRecord(MaterialRecVo materialRecVo) {
        String sql = "update factory_material set record_name = ?,team_name = ?,person_liable_name = ?,person_liable_phone = ?,material_person_name = ?,material_person_phone = ?,audit_state = 1,opr_date = now() where record_id = ?";
        return update(sql,materialRecVo.getRecordName(),materialRecVo.getTeamName(),materialRecVo.getPersonLiableName(),materialRecVo.getPersonLiablePhone(),materialRecVo.getMaterialPersonName(),materialRecVo.getMaterialPersonPhone(),materialRecVo.getRecordId());
    }

    @Override
    public void updateMaterialAuditRecord(Long recordId) {
        String sql = "update factory_audit_record set rec_state = 0 where record_id = ?";
        update(sql,recordId);
    }

    @Override
    public List<MaterialRecVo> queryMaterialRecList(String recordName, Long projectId,Long userId) {
        String sql = "select t.* from (select a.*,b.opr_user_id as nextUserId,b.opr_user_name as nextUserName,case b.opr_user_id = ? and a.audit_state <> 9 and a.audit_state <> 0 when true then 1 else 0 end as isMyAudit from (select a.* from factory_material a where a.record_name like '%" + recordName + "%' and a.project_id = ? order by a.opr_date desc) a inner join (select b.record_id,b.opr_user_id,b.opr_user_name from (SELECT t.record_id,MAX(t.rec_id) as rec_id from factory_audit_record t  GROUP BY t.record_id) a inner join factory_audit_record b on a.record_id = b.record_id and a.rec_id = b.rec_id ) b on a.record_id = b.record_id) t order by t.opr_date desc";
        return queryForList(sql,MaterialRecVo.class,userId,projectId);
    }

    @Override
    public void updateMaterialAuditRecord(Long recordId, Integer state) {
        String sql = "update factory_audit_record set opr_state = ? where rec_id = (select * from (select rec_id from factory_audit_record where record_id = ? order by rec_id desc) a limit 0,1)";
        update(sql,state,recordId);
    }
}
